package com.ruoyi.web.controller.front;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayConfig;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipaySystemOauthTokenRequest;
import com.alipay.api.response.AlipaySystemOauthTokenResponse;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.model.CannedAccessControlList;
import com.qcloud.cos.model.PutObjectRequest;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.model.LoginBody;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.entity.Result;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.framework.web.service.SysLoginService;
import com.ruoyi.system.domain.TbFeedback;
import com.ruoyi.system.domain.TbInvoiceRequests;
import com.ruoyi.system.domain.TbOrder;
import com.ruoyi.system.domain.TbPassenger;
import com.ruoyi.system.domain.vo.RideRecord;
import com.ruoyi.system.domain.vo.TbFeedbackRequest;
import com.ruoyi.system.mapper.TbPassengerMapper;
import com.ruoyi.system.service.ITbFeedbackService;
import com.ruoyi.system.service.ITbInvoiceRequestsService;
import com.ruoyi.system.service.ITbOrderService;

import com.ruoyi.system.service.ITbPassengerService;
import com.ruoyi.system.vo.InvoiceListVo;
import com.ruoyi.web.core.config.WechatMpConfig;

import com.ruoyi.web.controller.util.COSClientUtil;
import com.ruoyi.web.controller.util.FileTypeCheckerUtil;
import com.ruoyi.web.controller.util.SystemConstant;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import javax.servlet.http.HttpServletRequest;
import java.io.File;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


@Api(tags = "乘客端H5接口")
@RestController
@RequestMapping("/api/passenger")
public class PassengerController extends BaseController {

    private static final Logger log = LoggerFactory.getLogger(PassengerController.class);
    @Autowired
    private ITbFeedbackService feedbackService;
    @Autowired
    private ITbOrderService orderService;
    @Autowired
    private SysLoginService loginService;
    @Autowired
    private ITbPassengerService passengerService;

    @Autowired
    private ITbInvoiceRequestsService invoiceRequestsService;


    //投诉
    @ApiOperation(value = "投诉")
    @PostMapping("/complaint")
    public AjaxResult complaint(@RequestBody TbFeedbackRequest tbFeedback) {
        TbFeedback tbFeedback1 = new TbFeedback();
        BeanUtils.copyProperties(tbFeedback, tbFeedback1);
        return AjaxResult.success(feedbackService.insertTbFeedback(tbFeedback1) > 0 ? true : false);
    }
    //乘车记录
    @ApiOperation(value = "乘车记录列表")
    @GetMapping("/getTravelRecord")
    public AjaxResult getTravelRecord(@RequestParam(value = "pageNum", required = false, defaultValue = "1") Integer pageNum,
                                      @RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize,
                                      @RequestParam(value = "startDate", required =false ) String startDate,
                                      @RequestParam(value = "endDate", required =false ) String endDate) {
        Long userId = StpUtil.getLoginIdAsLong();
        //查询用户如果没有绑定手机号，先需要绑定手机号
        TbPassenger passenger = passengerService.selectTbPassengerById(userId);
        if(passenger!=null&& StrUtil.isBlankIfStr(passenger.getPassengerTel()))
        {
            return AjaxResult.success( 408);
        }
        PageHelper.startPage(pageNum, pageSize);
        TbOrder tbOrder = new TbOrder();
        tbOrder.setPassengerId(userId);
        tbOrder.setTransStatus("S");
        if(StrUtil.isNotBlank(startDate)&&StrUtil.isNotBlank(endDate))
        {
            tbOrder.setStartDate(startDate);
            tbOrder.setEndDate(endDate);
        }
        List<TbOrder> tbOrders = orderService.selectTbOrderList(tbOrder);
        PageInfo<TbOrder> pageInfo = new PageInfo<>(tbOrders);
        return AjaxResult.success(pageInfo);
    }

    @ApiOperation("乘客登录")
    @ApiImplicitParams({@ApiImplicitParam(name = "username", value = "用户名", required = true, dataType = "String"),
            @ApiImplicitParam(name = "code", value = "验证码", required = true, dataType = "String")})
    @PostMapping("/login")
    public AjaxResult login(@RequestBody LoginBody loginBody) {
        return AjaxResult.successBody(loginService.frontLoginByCode(loginBody.getUsername(), loginBody.getCode()));
    }
    /**
     * 通用上传请求（单个）
     */
    @ApiOperation(value = "上传文件")
    @PostMapping("/upload")
    public AjaxResult uploadFile(MultipartFile file) throws Exception
    {
        try
        {
            // 上传文件路径
            String filePath = RuoYiConfig.getUploadPath();
            // 上传并返回新文件名称
            String fileName = FileUploadUtils.upload(filePath, file);
            String url = RuoYiConfig.getImgUrl() + fileName;
            AjaxResult ajax = AjaxResult.success();
            ajax.put("url", url);
            ajax.put("fileName", fileName);
            ajax.put("newFileName", FileUtils.getName(fileName));
            ajax.put("originalFilename", file.getOriginalFilename());
            return AjaxResult.success(ajax);
        }
        catch (Exception e)
        {
            return AjaxResult.error(e.getMessage());
        }
    }




    @ApiOperation("上传图片到腾讯云对象存储")
    @PostMapping("/uploadToCOS")
    public Result uploadToCOS(HttpServletRequest request) throws IOException{

        // 获取文件
        List<MultipartFile> file = ((MultipartHttpServletRequest) request).getFiles("file");
        for (MultipartFile f:file) {
//            //判断文件上传格式
            if (!FileTypeCheckerUtil.isAllowedFileType(f)){
                return Result.error("文件类型错误!");
            }
        }
        File[] filePath = new File[file.size()];
        String[] url = new String[file.size()];

        String webUrl = "";
        if (!file.isEmpty()) {
            //上传文件路径
            String path = SystemConstant.DEFAULT_UPLOAD_URL;
            //获得上传文件名
            for (int i1 = 0; i1 < file.size(); i1++) {
                String fileName = file.get(i1).getOriginalFilename();
                assert fileName != null;
                int lastIndexOf = fileName.lastIndexOf(".");
                long time = System.currentTimeMillis();
                String date = "COS_" + time;
                //获取文件的后缀名 .jpg
                String suffix = fileName.substring(lastIndexOf);
                File filePath1 = new File(path + File.separator + date + suffix);
                //如果文件目录不存在，创建目录
                if (!filePath1.getParentFile().exists()) {
                    boolean mkdirs = filePath1.getParentFile().mkdirs();
                }
                file.get(i1).transferTo(filePath1);
                filePath[i1] = filePath1;
            }
        } else {
            return Result.error("上传失败");
        }

        for (int i = 0; i < filePath.length; i++) {
            //获取COSClient对象
            COSClient cosClient = COSClientUtil.getCosClient();
            // 设置存储桶名称和文件路径
            String bucketName = SystemConstant.bucketName;
            String key = "file/" + filePath[i].getName();
            File localFile = new File(filePath[i].getPath());
            try {
                // 上传文件到存储桶
                PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key, localFile);
                // 设置存储桶权限
                putObjectRequest.setCannedAcl(CannedAccessControlList.PublicRead);
                cosClient.putObject(putObjectRequest);
                File file1 = new File(filePath[i].getPath());
                String fileUrl = SystemConstant.OBJECT_STORAGE_URL + file1.getName();
                webUrl = file1.getName();
                System.out.println("文件上传存储桶成功");
                if (file1.delete()) {
                    System.out.println(file1.getName() + " 图片已被删除！");
                } else {
                    System.out.println("删除图片操作失败！");
                }
                url[i] = fileUrl;
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                // 关闭存储桶客户端
                cosClient.shutdown();
            }
        }
        return Result.success(webUrl);
    }


    //获取订单分页列表
    @RequestMapping("/getOrderList")
    public String getOrderList() {
        long loginIdAsLong = StpUtil.getLoginIdAsLong();
        return "getOrderList";
    }


    private final WechatMpConfig wechatMpConfig;

    // 推荐使用构造器注入
    public PassengerController(WechatMpConfig wechatMpConfig) {
        this.wechatMpConfig = wechatMpConfig;
    }

    // WechatAuthController.java 新增接口
    @GetMapping("/silent/callback")
    public AjaxResult silentCallback(@RequestParam("code") String code,
                                     @RequestParam(value = "type",defaultValue = "wechat") String type,
                                     HttpServletResponse response) {
        try {

            String openid="";
            String aliOpenid="";
            if(type.equalsIgnoreCase("wechat"))
            {
                openid=wechatOpenid(code);
            }else{
                aliOpenid=alipayOpenid(code);
            }

            //查询是否存在这个用户
            TbPassenger passenger = this.passengerService.searchPassengersBasedOnOpenId(openid,aliOpenid);
            if(passenger!=null)
            {
                StpUtil.login(passenger.getId(),"h5");
                return AjaxResult.success(StpUtil.getTokenInfo());
            }else{
                TbPassenger newPassenger = new TbPassenger();
                if(type.equalsIgnoreCase("wechat"))
                {
                    newPassenger.setOpenid(openid);
                }else {
                    newPassenger.setZfbId(aliOpenid);
                }
                this.passengerService.insertTbPassenger(newPassenger);
                StpUtil.login(newPassenger.getId(),"h5");
                return AjaxResult.success(StpUtil.getTokenInfo());
            }
        } catch (Exception e) {

           e.printStackTrace();
        }
        return null;
    }


    public String wechatOpenid(String code)
    {
        // 换取openid
        String url = String.format("%s?appid=%s&secret=%s&code=%s&grant_type=authorization_code",
                "https://api.weixin.qq.com/sns/oauth2/access_token",
                wechatMpConfig.getAppId(),
                wechatMpConfig.getAppSecret(),
                code);

        String result = HttpUtil.get(url);
        System.err.println(result);
        JSONObject json = JSONUtil.parseObj(result);
        log.info("json信息为",json.toStringPretty());
        if (json.containsKey("errcode")) {
            throw new RuntimeException(json.getStr("errmsg"));
        }

        String openid = json.getStr("openid");
        return openid;
    }

    public String alipayOpenid(String code)
    {
        String openid = "";
        AlipaySystemOauthTokenResponse json = null;
        try{
            // 换取openid
            json=getOauthTokenByCode(code);
            openid=json.getOpenId();
        }catch (Exception e)
        {
            e.printStackTrace();
        }

        return openid;
    }




    /**
     * 获取支付宝访问令牌
     *
     * @param code 授权码（当grantType为authorization_code时必填）
     * @param refreshToken 刷新令牌（当grantType为refresh_token时必填）
     * @param grantType 授权类型，支持authorization_code或refresh_token
     * @return AlipaySystemOauthTokenResponse 支付宝响应对象
     * @throws AlipayApiException 支付宝API异常
     */
    public static AlipaySystemOauthTokenResponse getOauthToken(String code, String refreshToken, String grantType) throws AlipayApiException, AlipayApiException {
        // 初始化SDK
        AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig());

        // 构造请求参数以调用接口
        AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();

        // 根据grantType设置相应参数
        if ("authorization_code".equals(grantType)) {
            if (code == null || code.isEmpty()) {
                throw new IllegalArgumentException("授权码不能为空当grantType为authorization_code时");
            }
            request.setCode(code);
        } else if ("refresh_token".equals(grantType)) {
            if (refreshToken == null || refreshToken.isEmpty()) {
                throw new IllegalArgumentException("刷新令牌不能为空当grantType为refresh_token时");
            }
            request.setRefreshToken(refreshToken);
        } else {
            throw new IllegalArgumentException("不支持的grantType: " + grantType);
        }

        request.setGrantType(grantType);
        log.error("request: " + request);
        // 执行请求
        return alipayClient.execute(request);
    }

    /**
     * 通过授权码获取访问令牌（简化方法）
     *
     * @param code 授权码
     * @return AlipaySystemOauthTokenResponse 支付宝响应对象
     * @throws AlipayApiException 支付宝API异常
     */
    public static AlipaySystemOauthTokenResponse getOauthTokenByCode(String code) throws AlipayApiException {
        return getOauthToken(code, null, "authorization_code");
    }
    /**
     * 获取支付宝配置
     * 注意：实际应用中，这些配置应该从配置文件或环境变量中读取
     */
    private static AlipayConfig getAlipayConfig() {
        String privateKey  = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCfLnX/16rh5rT7irKTWM/s8nmnMfl7lPaIi/oCDaGBSYmr4SXIA8A1nhIZ7NMve4xnt0jjyvJOxT9deFEXiyMlnpN1+2+QfrB2fXdqOYhL3puxKjP/k8sXjmSYljIIvqdWE8uLjnYHz1mzuaCG2fen+OHqYx2IeLwwzIPoG9rMB1OIQo1hItxvWj6CGVD+0MOha4ldXwBrj2UkL7i0n49YhWxbL6IT24vgcv+tyWLMFx0L+qzOvbXWSxutiS2wTdQ2ifut5QzP6diGL5lHyTRRUWCBgVzvvGeIb6lYK2jgAR8GiwaJ0TaFt5buwuUhXvDUIXvQlhxyRFW7WoMUgGbdAgMBAAECggEAXGi+e/4Z5/blDjpgnQWr/6RsV1G9wa6iyHZqdxKutb2ZPL0CD/GNfhL78yz3FNOmmPdgS02gCXac6IhWm1Jc3xQGCzIifEHv83m2/2XS6CidPeaANVj5R/2UDLj05vq3blMjkSrs/m+zZZDXzjFvgoYLsORFWtqsda/ky7SP+m1A292t0gDhl4Me0asgA5fcsE50SXIcUv/rjG2AJVkXjmx91f921FfyZKVSkB9F9AyymCsl3o9MVDJLwZ4J27h4pY0iL+Cbeaoi6aYJlpgQ6QH0m5vYuAvkKailUXFXAIy2gQXpWvPaMhklw4O8yw+3gIGKoAzff54+dqnwyfKeSQKBgQDtwpa9GS/Fpza9lZiYVeUBHf4zDj9NLCFKGP/y2E4Sm62BuqG7T0nl558JpFFscbHP1fbC8CHrnHEIaZUv7yZ5pbbGDdlz/3jwL4we2OIWG5TFWHZQgTh373Kthc04hsmAnpInfQl1/EoJ0249eclyoYxhTRyovijqoRkHEBzKFwKBgQCrZKc2mYl6ZAmtOGOyJEI/o5wHwkoek5PZlaf4cPXZiwmLrpTkyni08jIFJ0OuCaIts4+gwexJPYIQcKINfOHUlXFBPt02sc0ZrLgZoUNAK00rAmP1mGCRiJCT6qdyqtMm+Tp8q6nh5eXqQR9VqrPgPyUF1RHp79ig92X/fyNTKwKBgEYgeNl5jk+cDFdKwmFcJFl6AToJ373hYEg8q3FzP0PZywlShNV8g21eLdhoMOPtfOayU0AYF8kosWYrzib/QLfsmsY724GNPpyJSajni3e91tmGSA9ircciRw7LQkaD6vcWzkD7bkjwit3vELrtKu+2mnMwjV1wCR17OqiMphEtAoGAU5cMgnGRflKp8YSOAwTyFo2Z/KLCeXUqZ7U4rc+R6B6KckicL5WcF0wEH0VOGeRy520qwJGzxuirtY7pSkC892xHRzX8t78xs7LsOvvOi85SnYZV8CL3/iKnuKx6LE+qGdj1sHYcraLtZjmKqcJOZjEFwnlvejPS6HaglWKRfO8CgYB47C7/bHV9/9tzDe0/dE6rJ/vYVw/bxiUyU+/8YGUB0HxMoteSxO/UX+y6hCVsQ5iKyofSWgdYyA6baRZxmBEv8I9mg/+BcEt5tUrS/jbUF+lnmxSS+EzSDSLvLSIEYSFq6eR7VmDJlzUKg68W2lp8ww0s0Ak02R+JDj+IZzHQIQ==";
        String alipayPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgMfK1uwVx7v650SLuEenz91gsiTMA0V0AfrJN4a5ZZGiODvEhyNS6LNxnhpiuGo9OC0pfNos2ogfTYdDckwgRXN1HYaKvcfaM3sIzJ8p9HioiSDbWpH1+eRwN5d/lWApmJmSzV02SrWEhMZq1/3iWZ8l6bXCE2o2TseocUTETeV1MBFc87R81pB02r+MgwXBzHUAA9S+N6PGy+lNGTimWY4QyVnrnx3GLnvPlXNMXG1VOvSdErYvZQLbNyHnU3XmSsx2PUg+sgWfH3yFisOYy/u6U1tg8s+sNXNt8TJLXv6WTJ4DpB4u58SnJ+BPB7VINzNrjz36jX28lBECGMMOiwIDAQAB";

        AlipayConfig alipayConfig = new AlipayConfig();
        alipayConfig.setServerUrl("https://openapi.alipay.com/gateway.do");
        alipayConfig.setAppId("2021005139628464");
        alipayConfig.setPrivateKey(privateKey);
        alipayConfig.setFormat("json");
        alipayConfig.setAlipayPublicKey(alipayPublicKey);
        alipayConfig.setCharset("UTF-8");
        alipayConfig.setSignType("RSA2");
        return alipayConfig;
    }

    /**
     * 查询开票统计
     */
    @GetMapping("queryTheInvoicingStatistics")
    public AjaxResult queryTheInvoicingStatistics()
    {
        Long userId= StpUtil.getLoginIdAsLong();
        Object object =this.invoiceRequestsService.queryTheInvoicingStatistics(userId);
        return AjaxResult.success(object);
    }


    /**
     * 查询发票申请列表
     *
     * @param pageNum  页码
     * @param pageSize 页面大小
     * @return {@link AjaxResult }
     */
    @GetMapping("/queryInvoiceIssuingRecord")
    public AjaxResult queryInvoiceIssuingRecord(@RequestParam(value = "pageNum", required = false, defaultValue = "1") Integer pageNum,
                                                   @RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize)
    {
        TbInvoiceRequests tbInvoiceRequests = new TbInvoiceRequests();
        Long userId= StpUtil.getLoginIdAsLong();
        tbInvoiceRequests.setUserId(userId);
        PageHelper.startPage(pageNum, pageSize);
        List<TbInvoiceRequests> list = invoiceRequestsService.selectTbInvoiceRequestsList(tbInvoiceRequests);
        return AjaxResult.success(list);
    }


    /**
     * 查询可开票订单
     *
     * @param pageNum  页码
     * @param pageSize 页面大小
     * @return {@link AjaxResult }
     */
    @GetMapping("/queryOrderThatCanBeInvoiced")
    public AjaxResult queryOrderThatCanBeInvoiced(@RequestParam(value = "pageNum", required = false, defaultValue = "1") Integer pageNum,
                                                @RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize)
    {

        Long userId= StpUtil.getLoginIdAsLong();
        PageHelper.startPage(pageNum, pageSize);
        List<InvoiceListVo> list = invoiceRequestsService.queryOrderThatCanBeInvoiced(userId);
        return AjaxResult.success(list);
    }



    @PostMapping("/fillInBillingInformation")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult fillInBillingInformation(@RequestBody TbInvoiceRequests invoiceRequests)
    {

        Long userId= StpUtil.getLoginIdAsLong();
        invoiceRequests.setUserId(userId);
        if(StrUtil.isBlankIfStr(invoiceRequests.getInvoiceTitle())||
                StrUtil.isBlankIfStr(invoiceRequests.getInvoiceType())||
                StrUtil.isBlankIfStr(invoiceRequests.getContactPhone())||
                StrUtil.isBlankIfStr(invoiceRequests.getContactEmail())){
            return AjaxResult.error("参数不能为空");
       }
        TbOrder tbOrder=this.orderService.selectTbOrderById(invoiceRequests.getTripIds());
        if(tbOrder==null)
        {
            return AjaxResult.error("订单不存在");
        }
        invoiceRequests.setAmount(tbOrder.getTransAmount());
        invoiceRequests.setStatus(0L);
        invoiceRequests.setCreateTime(new Date());
        this.invoiceRequestsService.insertTbInvoiceRequests(invoiceRequests);
        return AjaxResult.success();
    }




}
